sendQuotationEmail
Email Template​

- 🇬🇧 English
- 🇮🇹 Italian
Function Name: sendQuotationEmail
Author: Domenico Cerone Creation Date: 02/10/2025
Last Reviewer: Domenico Cerone
Trigger: HTTPS (onRequest)
Purpose: Sends quotation emails for catalog orders with attachments downloaded from Firebase Storage. This Cloud Function retrieves order data, downloads the latest quotation file, and sends it via ZeptoMail with a professional email template.
Detailed Functionality​
1. INPUT VALIDATION AND PARAMETERS​
- Required Parameter:
orderId- ID of the document in 'CatalogOrders' collection - Validates that orderId is provided and not empty
- Accepts only POST requests
- Returns appropriate HTTP status codes for different error scenarios
2. CATALOG ORDER DATA RETRIEVAL​
- Queries 'CatalogOrders' collection using the provided orderId
- Validates that the order document exists
- Extracts
profile(recipient email),batch(optional batch identifier), andlist_quote_data(array of quotation objects) - Validates that both properties exist and list_quote_data is a non-empty array
3. QUOTATION DATA SELECTION​
- Takes the last element from
list_quote_dataarray (most recent quotation) - Extracts
quoteUrl(Firebase Storage URL),quoteName, andquoteNotes - Validates that quoteUrl exists and is a valid string
- Handles cases where quotation data is missing or invalid
4. NOTIFICATION PREFERENCE CHECK​
- Checks if the user has enabled the sendQuotationEmail notification in their notification preferences
- Verifies
notification_types.sendQuotationEmailfield in the profile - If notification is disabled (false): returns success without sending email
- If notification is enabled (true): proceeds with file download from Firebase Storage
- Provides clear logging about notification preference status
5. FILE DOWNLOAD FROM FIREBASE STORAGE​
- Downloads the file from the Firebase Storage URL
- Converts file to base64 format for email attachment
- Automatic MIME type detection based on file extension
- 30-second timeout to prevent network blocks
- Supports multiple file formats: PDF, Excel, Word, images, text files
6. MIME TYPE DETECTION​
- PDF:
application/pdf - Excel:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(xlsx) /application/vnd.ms-excel(xls) - Word:
application/vnd.openxmlformats-officedocument.wordprocessingml.document(docx) /application/msword(doc) - Images:
image/jpeg(jpg/jpeg) /image/png(png) - Text:
text/plain(txt) - Default:
application/octet-stream
7. EMAIL TEMPLATE CONFIGURATION​
- Uses ZeptoMail as the primary email service
- Template Key:
13ef.8598f19fbcc5adb.k1.b1523170-9d25-11f0-9d65-dad70ff08860.199952fde07 - Sender: "no-reply@arshades.com" (noreply)
- Professional template with quotation details and attachment
8. TEMPLATE VARIABLES​
{{quoteName}}: Name of the quotation{{quoteNotes}}: Additional notes about the quotation{{batch}}: Batch identifier (optional){{orderId}}: Order ID for reference
9. EMAIL ATTACHMENT HANDLING​
- Converts downloaded file to base64 format
- Attaches file with proper MIME type and filename
- Preserves original filename from Firebase Storage URL
- Handles large files with appropriate timeout settings
10. ERROR HANDLING AND VALIDATION​
- Comprehensive validation at each step
- Specific error messages for missing data
- Graceful handling of download failures
- Detailed logging for debugging purposes
- Proper HTTP status codes for different error scenarios
11. RESPONSE STRUCTURE​
- Success response includes all processed data
- Attachment information
- Template variables used
- ZeptoMail response details
- Detailed error information on failure
Input (Payload)​
Method: POST
Headers:
Content-Type: application/json
Body:
{
"orderId": "5AdIae1rNiSfaRa1HyyL"
}
Parameters:
orderId(string, required): Unique identifier of the catalog order document
Output (Success)​
{
"success": true,
"message": "Email di quotazione inviata con successo",
"recipientEmail": "user@example.com",
"attachmentFileName": "quote_1727618879438.pdf",
"quoteName": "Quote Q1 2025",
"quoteNotes": "Delivery expected in 15 working days...",
"batch": "BATCH_001",
"emailResponse": {
"data": {
"message": "Email sent successfully"
}
}
}
Response Properties:
success(boolean): Indicates if the operation was completed successfullymessage(string): Descriptive message about the operation resultrecipientEmail(string): Email address of the recipientattachmentFileName(string): Name of the attached filequoteName(string): Name of the quotationquoteNotes(string): Additional notes about the quotationbatch(string): Batch identifier (optional)emailResponse(object): Response from ZeptoMail service
Output (Error)​
{
"success": false,
"error": "Ordine con ID 5AdIae1rNiSfaRa1HyyL non trovato nella collezione CatalogOrders"
}
Common Error Scenarios:
- Missing orderId parameter
- Order not found in CatalogOrders collection
- Missing profile or list_quote_data properties
- Empty list_quote_data array
- Invalid quoteUrl in quotation data
- File download failure from Firebase Storage
- ZeptoMail service errors
Firestore Data Structure​
The CatalogOrder document must contain:
profile: recipient email addressbatch: batch identifier (optional)list_quote_data: array of quotation objects with structure:{
"quoteUrl": "https://firebasestorage.googleapis.com/...",
"quoteName": "Quote Q1 2025",
"quoteNotes": "Delivery expected in 15 working days...",
"quoteDate": "2025-01-15T00:00:00.000Z",
"timestamp": "2025-09-29T13:27:59.438Z",
"uploadedBy": "admin@arshades.com",
"fileName": "quote_1727618879438.pdf"
}
Testing​
URL (if HTTPS): http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail
Test with Emulator:
-
Start Firebase emulators:
firebase emulators:start --only functions -
Set Node.js version:
nvm use 20 -
Test with curl:
curl -X POST "http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail" \
-H "Content-Type: application/json" \
-d '{"orderId": "5AdIae1rNiSfaRa1HyyL"}'
Postman Testing:
- Method: POST
- URL:
http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail - Headers:
- Key:
Content-Type - Value:
application/json
- Key:
- Body: raw JSON (see examples above)
Deploy Command​
firebase deploy --only functions:sendQuotationEmail
Production URL​
Live Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/sendQuotationEmail
MAIL_TEMPLATE_KEY​
- Quotation Email:
13ef.8598f19fbcc5adb.k1.b1523170-9d25-11f0-9d65-dad70ff08860.199952fde07
Function Name: sendQuotationEmail
Autore: Domenico Cerone Data di creazione: 02/10/2025
Last Reviewer: Domenico Cerone
Trigger: HTTPS (onRequest)
Purpose: Invia email di quotazione per ordini catalogo con allegati scaricati da Firebase Storage. Questa Cloud Function recupera i dati dell'ordine, scarica l'ultimo file di quotazione e lo invia tramite ZeptoMail con un template email professionale.
Funzionamento Dettagliato​
1. VALIDAZIONE INPUT E PARAMETRI​
- Parametro Richiesto:
orderId- ID del documento nella collezione 'CatalogOrders' - Valida che orderId sia fornito e non vuoto
- Accetta solo richieste POST
- Restituisce codici di stato HTTP appropriati per diversi scenari di errore
2. RECUPERO DATI ORDINE CATALOGO​
- Interroga la collezione 'CatalogOrders' usando l'orderId fornito
- Valida che il documento ordine esista
- Estrae
profile(email destinatario),batch(identificativo batch opzionale) elist_quote_data(array di oggetti quotazione) - Valida che entrambe le proprietà esistano e list_quote_data sia un array non vuoto
3. SELEZIONE DATI QUOTAZIONE​
- Prende l'ultimo elemento dall'array
list_quote_data(quotazione più recente) - Estrae
quoteUrl(URL Firebase Storage),quoteNameequoteNotes - Valida che quoteUrl esista e sia una stringa valida
- Gestisce i casi in cui i dati della quotazione sono mancanti o non validi
4. CONTROLLO PREFERENZE NOTIFICHE​
- Controlla se l'utente ha abilitato sendQuotationEmail nelle sue preferenze di notifica
- Verifica il campo
notification_types.sendQuotationEmailnel profilo - Se la notifica è disabilitata (false): restituisce successo senza inviare email
- Se la notifica è abilitata (true): procede con il download del file da Firebase Storage
- Fornisce logging chiaro sullo stato delle preferenze di notifica
5. DOWNLOAD FILE DA FIREBASE STORAGE​
- Scarica il file dall'URL di Firebase Storage
- Converte il file in formato base64 per allegato email
- Rilevamento automatico del tipo MIME basato sull'estensione del file
- Timeout di 30 secondi per evitare blocchi di rete
- Supporta più formati di file: PDF, Excel, Word, immagini, file di testo
6. RILEVAMENTO TIPO MIME​
- PDF:
application/pdf - Excel:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(xlsx) /application/vnd.ms-excel(xls) - Word:
application/vnd.openxmlformats-officedocument.wordprocessingml.document(docx) /application/msword(doc) - Immagini:
image/jpeg(jpg/jpeg) /image/png(png) - Testo:
text/plain(txt) - Default:
application/octet-stream
7. CONFIGURAZIONE TEMPLATE EMAIL​
- Utilizza ZeptoMail come servizio email principale
- Template Key:
13ef.8598f19fbcc5adb.k1.b1523170-9d25-11f0-9d65-dad70ff08860.199952fde07 - Mittente: "no-reply@arshades.com" (noreply)
- Template professionale con dettagli quotazione e allegato
8. VARIABILI TEMPLATE​
{{quoteName}}: Nome della quotazione{{quoteNotes}}: Note aggiuntive sulla quotazione{{batch}}: Identificativo del batch (opzionale){{orderId}}: ID dell'ordine per riferimento
9. GESTIONE ALLEGATI EMAIL​
- Converte il file scaricato in formato base64
- Allega il file con tipo MIME e nome file appropriati
- Preserva il nome file originale dall'URL di Firebase Storage
- Gestisce file di grandi dimensioni con timeout appropriati
10. GESTIONE ERRORI E VALIDAZIONE​
- Validazione completa ad ogni passaggio
- Messaggi di errore specifici per dati mancanti
- Gestione elegante dei fallimenti di download
- Logging dettagliato per debug
- Codici di stato HTTP appropriati per diversi scenari di errore
11. STRUTTURA RISPOSTA​
- Risposta di successo include tutti i dati elaborati
- Informazioni allegato
- Variabili template utilizzate
- Dettagli risposta ZeptoMail
- Informazioni dettagliate errore in caso di fallimento
Input (Payload)​
Metodo: POST
Headers:
Content-Type: application/json
Body:
{
"orderId": "5AdIae1rNiSfaRa1HyyL"
}
Parametri:
orderId(string, richiesto): Identificatore unico del documento ordine catalogo
Output (Successo)​
{
"success": true,
"message": "Email di quotazione inviata con successo",
"recipientEmail": "user@example.com",
"attachmentFileName": "quote_1727618879438.pdf",
"quoteName": "Quote Q1 2025",
"quoteNotes": "Delivery expected in 15 working days...",
"batch": "BATCH_001",
"emailResponse": {
"data": {
"message": "Email sent successfully"
}
}
}
Proprietà Risposta:
success(boolean): Indica se l'operazione è stata completata con successomessage(string): Messaggio descrittivo sul risultato dell'operazionerecipientEmail(string): Indirizzo email del destinatarioattachmentFileName(string): Nome del file allegatoquoteName(string): Nome della quotazionequoteNotes(string): Note aggiuntive sulla quotazionebatch(string): Identificativo del batch (opzionale)emailResponse(object): Risposta dal servizio ZeptoMail
Output (Errore)​
{
"success": false,
"error": "Ordine con ID 5AdIae1rNiSfaRa1HyyL non trovato nella collezione CatalogOrders"
}
Scenari di Errore Comuni:
- Parametro orderId mancante
- Ordine non trovato nella collezione CatalogOrders
- Proprietà profile o list_quote_data mancanti
- Array list_quote_data vuoto
- quoteUrl non valido nei dati quotazione
- Fallimento download file da Firebase Storage
- Errori servizio ZeptoMail
Struttura Dati Firestore​
Il documento CatalogOrder deve contenere:
profile: indirizzo email del destinatariobatch: identificativo del batch (opzionale)list_quote_data: array di oggetti quotazione con struttura:{
"quoteUrl": "https://firebasestorage.googleapis.com/...",
"quoteName": "Quote Q1 2025",
"quoteNotes": "Delivery expected in 15 working days...",
"quoteDate": "2025-01-15T00:00:00.000Z",
"timestamp": "2025-09-29T13:27:59.438Z",
"uploadedBy": "admin@arshades.com",
"fileName": "quote_1727618879438.pdf"
}
Testing​
URL (if HTTPS): http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail
Test con Emulator:
-
Avvia gli emulatori Firebase:
firebase emulators:start --only functions -
Imposta la versione Node.js:
nvm use 20 -
Test con curl:
curl -X POST "http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail" \
-H "Content-Type: application/json" \
-d '{"orderId": "5AdIae1rNiSfaRa1HyyL"}'
Test con Postman:
- Metodo: POST
- URL:
http://127.0.0.1:5001/arshadesstaging/europe-central2/sendQuotationEmail - Headers:
- Key:
Content-Type - Value:
application/json
- Key:
- Body: raw JSON (vedi esempi sopra)
Deploy Command​
firebase deploy --only functions:sendQuotationEmail
URL di Produzione​
Funzione Live: https://europe-central2-arshades-7e18a.cloudfunctions.net/sendQuotationEmail
MAIL_TEMPLATE_KEY​
- Quotation Email:
13ef.8598f19fbcc5adb.k1.b1523170-9d25-11f0-9d65-dad70ff08860.199952fde07